package com.zhenxiang.juc.lock.productComsumer;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author : James
 * @Create : 2021-12-21-11:20
 * @Description :  生产者消费者 互相通讯 Lock 版
 */
public class ProductConsumerLock2 {

    public static void main(String[] args) {
      Data2 data2 = new Data2();

      new Thread(()->{
          for (int i = 0; i < 10; i++) {
              try {
                  data2.increment();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      },"A").start();


      new Thread(()->{
          for (int i = 0; i <10; i++) {
              try {
                  data2.decrement();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      },"B").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try {
                    data2.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"C").start();


        new Thread(()->{
            for (int i = 0; i <10; i++) {
                try {
                    data2.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"D").start();


    }
}


// 资源类
 class Data2 {

    private int num = 0;
    Lock lock = new ReentrantLock();
    // 监视器
    Condition condition = lock.newCondition();

    // 自增 +1
    public void increment() throws InterruptedException {
        lock.lock();
        try {
            while (num != 0) {
                condition.await();
            }
            num++;
            System.out.println(Thread.currentThread().getName() + "====>" + num);
            // 唤醒所有等待线程。
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    // 递减 -1
    public void decrement() throws InterruptedException {
        lock.lock();
        try {
            while (num == 0) {
                condition.await();
            }
            num--;
            System.out.println(Thread.currentThread().getName() + "====>" + num);
            // 唤醒所有等待线程。
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}
